package com.woniuxy.sddfp.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.woniuxy.sddfp.common.constant.redis.RedisConstant;
import com.woniuxy.sddfp.common.constant.user.UserConstant;
import com.woniuxy.sddfp.common.exception.Assert;
import com.woniuxy.sddfp.common.model.dto.user.LoginDto;
import com.woniuxy.sddfp.common.model.dto.user.UserRegisterDto;
import com.woniuxy.sddfp.common.model.vo.user.LoginVo;
import com.woniuxy.sddfp.common.result.Result;
import com.woniuxy.sddfp.common.result.enums.impl.BusinessCode;
import com.woniuxy.sddfp.system.entity.User;
import com.woniuxy.sddfp.system.entity.UserDetail;
import com.woniuxy.sddfp.system.mapper.UserDetailMapper;
import com.woniuxy.sddfp.system.mapper.UserMapper;
import com.woniuxy.sddfp.system.service.IUserDetailService;
import com.woniuxy.sddfp.system.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Objects;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private IUserDetailService iUserDetailService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Transactional(propagation= Propagation.REQUIRED)
    @Override
    public Result  register(UserRegisterDto userRegisterDto) {
        saveUser(userRegisterDto);
        return Result.ok();
    }

    private void saveUser(UserRegisterDto userRegisterDto) {
        User user = new User();
        //正常的写法 需要对 user的pwd 进行加密
        BeanUtil.copyProperties(userRegisterDto,user);
        user.setUserType("1");
        user.setUserStatus(true);
        save(user);
        //保存用户详情
        UserDetail userDetail = new UserDetail();
        userDetail.setId(user.getId());
        userDetail.setUserName(userRegisterDto.getUserName());
        userDetail.setPhone(userRegisterDto.getPhone());
        userDetail.setBorrowMoney(new BigDecimal("0"));
        String uuid = UUID.randomUUID().toString().substring(0, 10);
        userDetail.setUserCode("UC_" + uuid);
        userDetail.setCardBindStatus(false);
        iUserDetailService.save(userDetail);
    }


    @Override
    public LoginVo login(LoginDto loginDto) {
        return loginDto.getIsPhoneLogin() ? userPhoneLogin(loginDto) : userPwdLogin(loginDto);
    }

    private LoginVo userPwdLogin(LoginDto loginDto) {
        //1 查询用户 是否存在
        //查询对象
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(User.class);

        //条件设置
        queryWrapper.eq(User::getUserName, loginDto.getLoginName());
        //调用service中的  getOne方法
        User user = getOne(queryWrapper);
        Assert.error(user, BusinessCode.USER_LOGIN_ERROR);
        //2、比对密码
        Assert.error(!user.getPwd().equals(loginDto.getLoginSecret()), BusinessCode.USER_LOGIN_ERROR);

        //3、把 user 转成 loginVo
        LoginVo loginVo = getLoginVo(user);

        return loginVo;
    }

    private LoginVo getLoginVo(User user) {

        return LoginVo.builder()
                .id(user.getId())
                .userName(user.getUserName())
                .phone(user.getPhone())
                .token("")
                .build();

    }

    private LoginVo userPhoneLogin(LoginDto loginDto) {
        String key = RedisConstant.SMS_PREFIX + loginDto.getLoginName();
        String code = stringRedisTemplate.opsForValue().get(key);
        Assert.error(!StringUtils.hasText(code), BusinessCode.USER_NULL_CODE_ERROR);
        //02  通过手机号码查询用户是否存在   存在\登录     不存在 注册 返回登录用户
        //判断验证码
        Assert.error(!code.equals(loginDto.getLoginSecret()), BusinessCode.USER_VERIFY_CODE_ERROR);
        LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery(User.class).eq(User::getPhone, loginDto.getLoginName());
        User user = getOne(lambdaQueryWrapper);
        if (Objects.isNull(user)){  //null 处理  注册
            //注册
            UserRegisterDto userRegisterDto = new UserRegisterDto();
            userRegisterDto.setUserName(loginDto.getLoginName());
            userRegisterDto.setPwd("123456");
            userRegisterDto.setPhone(loginDto.getLoginName());

            //添加成功
            saveUser(userRegisterDto);

            //查询刚注册的用户 返回 登录对象
            user = getOne(lambdaQueryWrapper);
        }
        return getLoginVo(user);
    }
}
